<?php
namespace Module\Controller;

use Zend\Filter\Compress\Zip;

use Zend\Mvc\Controller\AbstractActionController;

use Module\Form\UploadForm;
use Module\Model\UploadFormFilter;
use Zend\Validator\File\Size;

define('DS', DIRECTORY_SEPARATOR);

class UploadController extends AbstractActionController
{
	protected $modulesTable;
	
        protected $controllersTable;
	
	public function getModuleTable()
	{
		if(!$this->modulesTable)
		{
			$this->modulesTable = $this->getServiceLocator()->get('Module\Model\ModuleTable');
		}
		
		return $this->modulesTable;
	}
        
        
	public function getControllersTable()
	{
		if(!$this->controllersTable)
		{
			$this->controllersTable = $this->getServiceLocator()->get('Module\Model\ControllersTable');
		}
		
		return $this->controllersTable;
	}
        
        protected function copyDirectory( $path, $dest )
        {
            if( is_dir($path) )
            {
                @mkdir( $dest );
                $objects = scandir($path);
                if( sizeof($objects) > 0 )
                {
                    foreach( $objects as $file )
                    {
                        if( $file == "." || $file == ".." )
                            continue;
                        // go on
                        if( is_dir( $path.DS.$file ) )
                        {
                            $this->copyDirectory( $path.DS.$file, $dest.DS.$file );
                        }
                        else
                        {
                            copy( $path.DS.$file, $dest.DS.$file );
                        }
                    }
                }
                return true;
            }
            elseif( is_file($path) )
            {
                return copy($path, $dest);
            }
            else
            {
                return false;
            }
        }
        
        protected function deleteDirectory($dir) 
        {
            if (!file_exists($dir)) 
            {
                return true;
            }
                
            if (!is_dir($dir) || is_link($dir)) 
            {
                return unlink($dir);
            }
            
            foreach (scandir($dir) as $item) {
                if ($item == '.' || $item == '..') continue;
                if (!$this->deleteDirectory($dir . DS . $item)) {
                    chmod($dir . DS . $item, 0777);
                    if (!$this->deleteDirectory($dir . DS . $item)) return false;
                };
            }
            return rmdir($dir);
        } 
        
	
	public function indexAction()
	{
		
		$uploadform = new UploadForm();
		
		$request = $this->getRequest();
		
		if($request->isPost())
		{
			$uploadFilter = new UploadFormFilter();
			
			$uploadform->setInputFilter($uploadFilter->getInputFilter());
			
			$nonFile = $request->getPost()->toArray();
			
			$file = $this->params()->fromFiles('fileupload');
			
// 			$data = array_merge(
//                  $nonFile,
//                  array('fileupload'=> $File['name'])
//              );
			
			$uploadform->setData(array('fileupload'=> $file['name']));
			
			if ($uploadform->isValid()) {
				
                            $size = new Size(array('min'=>1)); //minimum bytes filesize
	     
			    $adapter = new \Zend\File\Transfer\Adapter\Http(); 

			    $adapter->setValidators(array($size), $file['name']);
			     
			    if (!$adapter->isValid()){
			    	
			        $dataError = $adapter->getMessages();
			        
			        $error = array();
			        
			        foreach($dataError as $key => $row)
			        {
			            $error[] = $row;
			        } 
			        
			        $uploadform->setMessages(array('fileupload' => $error));
			        
			    } else {
			    	
			        //$adapter->setDestination(dirname(__DIR__).'/../../data/images/upload');
			        
			    	$dest_dir = ROOT_PATH.'/data/temp';
			    	
			        $adapter->setDestination($dest_dir);
			        
			        if($adapter->receive($file['name'])) 
			        {
			        	
			        	/*
			        	 * Extract
			        	 */
			        	
			        	$src = $dest_dir .DS .$file['name'];
			        	 
			        	$options = array(
			        			'archive' => $src,
			        			'target'  => $dest_dir,
			        	);
			        	 
			        	$zipEngine = new Zip($options);
			        	
			        	$zipEngine->decompress($src);
			        	
			        	/*
			        	 * End extract
			        	 */
			        	
			        	/*
			        	 * Register new module
			        	 */
			        	$folder_name = strpos($file['name'], '.') ? substr($file['name'], 0, strpos($file['name'], '.')) : $file['name'];
							        	
                                        $folder_path = $dest_dir.DS.$folder_name;
                                        
                                        $config_file_path = $folder_path.DS.'config.xml';

                                        if(!file_exists($config_file_path))
                                        {
                                                $this->flashMessenger()->addMessage("Module package is missing some configuration infomation. Please contact the author to get the help.");
                                        }

                                        $xml = simplexml_load_file($config_file_path);
                                        
                                        $data = array(

                                                        'key_name' 		=> $xml->key_name,

                                                        'name' 			=> $xml->name,

                                                        'description'           => $xml->description,

                                                        'author' 		=> $xml->author,

                                                        'version' 		=> $xml->version,
                                                        
                                                        'zend_src' 		=> $xml->zend_src,

                                                        'ext_src'		=> $xml->ext_src,
                                            
                                                        'icon'                  => $xml->icon,

                                                        'state'			=> 0,

                                        );
                                        

                                        if($this->getModuleTable()->isExist($data['key_name']))
                                        {
                                                $this->flashMessenger()->addMessage("This module is already existed. If you want to reinstall, please remove it from Module Manager first and then install it again.");
                                        }
                                        else
                                        {
                                                //Copy source code
                                                $zend_src = $folder_path.DS.$xml->zend_src;
                                                
                                                $zend_dest = ROOT_PATH.'/modules/'.$xml->key_name;
                                                
                                                if(!is_dir($zend_dest))
                                                {
                                                    mkdir($zend_dest);
                                                }
                                                
                                                $this->copyDirectory($zend_src, $zend_dest);
                                                
                                                //Copy ext code
                                                $ext_src = $folder_path.DS.$xml->ext_src;
                                                
                                                $ext_dest = ROOT_PATH.'/../app/modules/'.$xml->key_name;
                                                
                                                if(!is_dir($ext_dest))
                                                {
                                                    mkdir($ext_dest);
                                                }
                                                
                                                $this->copyDirectory($ext_src, $ext_dest);
                                                
                                                
                                                //Save info into db
                                                $mid = $this->getModuleTable()->save($data);
                                                
                                                //Save controller list to controller table
                                                $controllers = (array)$xml->controllers->name;
                                                
                                                if(is_array($controllers))
                                                {
                                                    foreach($controllers as $controller)
                                                    {
                                                        $this->getControllersTable()->getTableGateway()->insert(array('mid' => $mid, 'controller_name' => $controller));
                                                    }
                                                }
                                                
                                                $link = $this->getEvent()->getRouter()->assemble(array(), array('name' => 'module'));

                                                $this->flashMessenger()->addMessage('Install module successful! Enable it at <a href="'.$link.'">Module Manager</a>');
                                        }

                                        //Delete zip file
                                        unlink($src);
                                        
                                        //Delete temp/{module}
                                        $this->deleteDirectory($folder_path.DS);

                                        return $this->redirect()->toRoute('module/process', array('controller' => 'index', 'action' => 'index'));

			        }
			        else
			        {
			        	$this->flashMessenger()->addMessage('Receiving file failed!');

			        }
			        
			    }  
			}
		}
		
		return array('uploadform' => $uploadform, 'messages' => $this->flashMessenger()->getMessages());
	}
}